package com.awa.study;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class A01_Student_management_system
{
    // ctrl + shift + U 小写变大写
    private static final String ADD_STUDENT = "1";
    private static final String DELETE_STUDENT = "2";
    private static final String UPDATE_STUDENT = "3";
    private static final String QUERY_STUDENT = "4";
    private static final String EXIT = "5";
    //增加代码可读性
    public static void main(String[] args)
    {
        //流程图：
        /*switch (choose)
        {
            case 1:添加学生 --> 方法(添加)
            case 2:删除学生 --> 方法(删除)
            case 3:修改学生 --> 方法(修改)
            case 4:查询学生 --> 方法(查询)
            case 5:退出
        }
        方法(添加)
        {
            - id 唯一
        }
        方法(删除)
        {
            - id 存在 - 删除
            - id 不存在 - 提示不存在并返回初始菜单
        }
        方法(修改)
        {
            - id 存在 - 继续录入其他信息
            - id 不存在 - 提示不存在并返回初始菜单
        }
        方法(查询)
        {
            - 没有学生信息 - 提示无学生信息，请添加后再查询
            - 有学生信息 - 按格式输出
        }*/

        //升级版 - 流程图
        /*switch (choose)
        {
            case 1:
                登录
            case 2:
                注册
            case 3:
                忘记密码
            default:
                没有这个选项
        }
        方法(登录) - 2
        {
            1.键盘录入用户名
            2.键盘录入密码
            3.获取一个验证码
            4.键盘录入验证码

            验证：
            1.判断用户名是否存在，如果不存在，直接提示未注册
            2.如果正确，登陆成功
            3.如果错误，三次机会
        }
        方法(注册) - 1
        {
            1.用户名
                1.用户名唯一 - contains
                2.用户名长度必须在 3 - 15 位之间 - length()
                3.只能是字母加数字的组合，但是不能是纯数字 - 设定字符范围，统计用户名中有多少个字符在 a - z A - Z，大于等于零
            2.密码 - 键盘输入两次，两次一致才能进行注册 - Scanner
            3.身份证号码需要验证
                1.长度为 18 位 - length()
                2.不能以 0 为开头 - charAt(0)
                3.前 17 位必须是数字 - 遍历前 17 位
                4.最后一位还可以是 X / x - 获取最后一个字符 -  0 ~ 9 / X / x
            4.手机号验证
                1.长度为 11 位 - length()
                2.不能以 0 为开头 - charAt(0)
                3.必须都是数字 - 遍历
            5.创建对象，导入数据
        }
        方法(忘记密码) - 3
        {
            1.键盘录入用户名，判断是否存在，如果不存在直接提示未注册
            2.存在 - 键盘录入身份证号码和手机号码
            3.判断是否一致，如果一致，则提示输入密码进行修改，如果不一致，则提示账号信息不匹配，修改失败
            4.注：如果进行到第二步，说明用户名存在
        }*/

        Scanner sc = new Scanner(System.in);
        ArrayList<A03_Users> userList = new ArrayList<>();
        boolean flag;
        loop:while (true)
        {
            System.out.println("欢迎来到学生管理系统");
            System.out.print("请选择操作：1-登录，2-注册，3-忘记密码:>");
            String choice = sc.next();
            switch (choice)
            {
                case "1" ->
                {
                    flag = signIn(userList);
                    if (flag)
                    {
                        break loop;
                    }
                }
                case "2" -> register(userList);
                case "3" -> forgetPassword(userList);
            }
        }


        ArrayList<A02_Student> list = new ArrayList<>();
        loop:while (true)
        {
            System.out.println("---------------欢迎来到黑马学生管理系统---------------");
            System.out.println("1.添加学生");
            System.out.println("2.删除学生");
            System.out.println("3.修改学生");
            System.out.println("4.查询学生");
            System.out.println("5.退出");
            System.out.print("请输入您的选择:>");
            String choose = sc.next();
            switch (choose)
            {
                case ADD_STUDENT -> addStudent(list);
                case DELETE_STUDENT -> deleteStudent(list);
                case UPDATE_STUDENT -> updateStudent(list);
                case QUERY_STUDENT -> queryStudent(list);
                case EXIT ->
                {
                    System.out.println("退出");
                    break loop;//退出当前标识符指定的循环
                    // System.exit(0); 停止虚拟机运行
                }
                default -> System.out.println("没有这个选项");
            }
        }

    }
    //添加学生
    public static void addStudent(ArrayList<A02_Student> list)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("添加学生");
        A02_Student stu = new A02_Student();
        while (true)
        {
            System.out.print("请输入学生 id:>");
            String id = sc.next();
            int flag = idContains(list, id);
            if (flag >= 0)
            {
                System.out.println("id 已存在，请重新输入");
            }
            else
            {
                stu.setId(id);
                break;
            }
        }
        System.out.print("请输入学生姓名:>");
        String name = sc.next();
        stu.setName(name);
        System.out.print("请输入学生年龄:>");
        int age = sc.nextInt();
        stu.setAge(age);
        System.out.print("请输入学生地址:>");
        String address = sc.next();
        stu.setAddress(address);
        list.add(stu);
        System.out.println("添加成功");
    }
    //删除学生
    public static void deleteStudent(ArrayList<A02_Student> list)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("删除学生");
        System.out.print("请输入学生 id:>");
        String id = sc.next();
        int index = idContains(list, id);
        if (index >= 0)
        {
            list.remove(index);
            System.out.println("删除成功");
        }
        else
        {
            System.out.println("id 不存在");
        }
    }
    //修改学生
    public static void updateStudent(ArrayList<A02_Student> list)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("修改学生");
        System.out.print("请输入学生 id:>");
        String id = sc.next();
        int index = idContains(list, id);
        if (index >= 0)
        {
            loop:while (true)
            {
                System.out.print("请输入要修改的信息(1-id,2-姓名,3-年龄,4-地址,5-退出):>");
                String choose = sc.next();
                switch (choose)
                {
                    case "1":
                        while (true)
                        {
                            System.out.print("请输入更改后的 id:>");
                            String newId = sc.next();
                            int flag = idContains(list, newId);
                            if (flag >= 0)
                            {
                                System.out.print("id 已存在，请重新输入:>");
                            }
                            else
                            {
                                list.get(index).setId(newId);
                                System.out.println("修改成功");
                                break;
                            }
                        }
                        break;

                    case "2":
                        System.out.print("请输入更改后的姓名:>");
                        String newName = sc.next();
                        list.get(index).setName(newName);
                        System.out.println("修改成功");
                        break;
                    case "3":
                        System.out.print("请输入更改后的年龄:>");
                        int newAge = sc.nextInt();
                        list.get(index).setAge(newAge);
                        System.out.println("修改成功");
                        break;
                    case "4":
                        System.out.print("请输入更改后的地址:>");
                        String newAddress = sc.next();
                        list.get(index).setAddress(newAddress);
                        System.out.println("修改成功");
                        break;
                    case "5":
                        break loop;
                    default:
                        System.out.println("没有这个选项");
                        break;
                }
            }
        }
        else
        {
            System.out.println("id 不存在");
        }
    }
    //查询学生
    public static void queryStudent(ArrayList<A02_Student> list)
    {
        System.out.println("查询学生");
        if (list.size() == 0)
        {
            System.out.println("当前无学生信息，请添加后再查询");
        }
        else
        {
            System.out.println("id       \t  姓名\t  年龄\t  家庭住址\t");
            for (int i = 0; i < list.size(); i++)
            {
                System.out.println(list.get(i).getId() + " \t" + "  " + list.get(i).getName() + " \t" + "  " +list.get(i).getAge() + " \t" + "  " + list.get(i).getAddress());
            }
        }
    }
    public static int idContains(ArrayList<A02_Student> list, String str)
    {
        int index = -1;
        for (int i = 0; i < list.size(); i++)
        {
            if (str.equals(list.get(i).getId()))
            {
                index = i;
                break;
            }
        }
        return index;
    }
    public static void register(ArrayList<A03_Users> userList)
    {
        System.out.println("注册");
        Scanner sc = new Scanner(System.in);
        String id;
        String username;
        String password;
        String phoneNumber;
        while (true)
        {
            System.out.print("请输入用户名:>");
            username = sc.next();
            boolean flag = isUsernameLegal(userList, username);
            if (flag)
            {
                break;
            }
        }
        while (true)
        {
            System.out.print("请输入密码:>");
            String password1 = sc.next();
            System.out.print("请再次输入密码:>");
            String password2 = sc.next();
            if (password1.equals(password2))
            {
                password = password1;
                break;
            }
            else
            {
                System.out.println("两次输入密码不一致，请重新输入");
            }
        }
        while (true)
        {
            System.out.print("请输入身份证号码:>");
            id = sc.next();
            boolean flag = isIdLegal(id);
            if (flag)
            {
                break;
            }
        }
        while (true)
        {
            System.out.print("请输入手机号:>");
            phoneNumber = sc.next();
            boolean flag = isPhoneNumberLegal(phoneNumber);
            if (flag)
            {
                break;
            }
        }
        A03_Users user = new A03_Users();
        user.setId(id);
        user.setUsername(username);
        user.setPassword(password);
        user.setPhoneNumber(phoneNumber);
        userList.add(user);
        System.out.println("注册成功");
    }
    public static boolean signIn(ArrayList<A03_Users> userList)
    {
        boolean flag = false;
        System.out.println("登录");
        Scanner sc = new Scanner(System.in);
        loop:while (true)
        {
            System.out.print("请输入用户名(按 Q 跳转到注册界面):>");
            String username = sc.next();
            if (username.equalsIgnoreCase("Q"))
            {
                register(userList);
                break;
            }
            else
            {
                int index = usernameContains(userList, username);
                if (index < 0)
                {
                    System.out.println("用户名不存在，请重新输入");
                }
                else
                {
                    for (int i = 0; ; )
                    {
                        System.out.print("请输入密码:>");
                        String password = sc.next();
                        String realCode = getVerificationCode();
                        System.out.println("验证码是:" + realCode);
                        System.out.print("请输入验证码:>");
                        String code = sc.next();
                        if (code.equalsIgnoreCase(realCode))
                        {
                            if (password.equals(userList.get(index).getPassword()))
                            {
                                System.out.println("登陆成功");
                                flag = true;
                                break loop;
                            }
                            else
                            {
                                if (i != 2)
                                {
                                    System.out.println("密码错误，请重新输入，您还剩下 " + (2 - i) + " 次机会");
                                    i ++;
                                }
                                else
                                {
                                    System.out.println("错误次数过多，您的账户已被冻结，请联系管理员");
                                    break loop;
                                }
                            }
                        }
                        else
                        {
                            System.out.println("验证码错误，请重新输入");
                        }
                    }
                }
            }
        }
        return flag;
    }
    public static void forgetPassword(ArrayList<A03_Users> userList)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("忘记密码");
        loop:while (true)
        {
            System.out.print("请输入您的用户名:>");
            String username = sc.next();
            int index = usernameContains(userList, username);
            if (index < 0)
            {
                System.out.println("用户未注册");
                mid:while (true)
                {
                    System.out.print("按 A 重新输入用户名，按 B 跳转到注册界面，按 C 退出:>");
                    String tmp = sc.next();
                    switch (tmp)
                    {
                        case "A":
                            break mid;
                        case "B":
                            register(userList);
                            break loop;
                        case "C":
                            break loop;
                        default:
                            System.out.println("没有这个选项");
                            break;
                    }
                }
            }
            else
            {
                System.out.print("请输入身份证号码:>");
                String id = sc.next();
                System.out.print("请输入手机号码:>");
                String phoneNumber = sc.next();
                if (id.equals(userList.get(index).getId()) && phoneNumber.equals(userList.get(index).getPhoneNumber()))
                {
                    System.out.print("请输入修改后的密码:>");
                    String password = sc.next();
                    userList.get(index).setPassword(password);
                    System.out.println("修改成功");
                }
                else
                {
                    System.out.println("账号信息不匹配，修改失败");
                }
                break;
            }
        }
    }
    public static int usernameContains(ArrayList<A03_Users> userList, String username)
    {
        int index = -1;
        for (int i = 0; i < userList.size(); i++)
        {
            if (username.equals(userList.get(i).getUsername()))
            {
                index = i;
                break;
            }
        }
        return index;
    }
    public static boolean isUsernameLegal(ArrayList<A03_Users> userList, String username)
    {
        int count = 0;
        int len = username.length();
        if (len < 3)
        {
            System.out.println("用户名过短，请重新输入");
            return false;
        }
        else if (len > 15)
        {
            System.out.println("用户名过长，请重新输入");
            return false;
        }
        for (int i = 0; i < username.length(); i++)
        {
            if ((username.charAt(i) > 'Z' && username.charAt(i) < 'a') || username.charAt(i) < '0' || (username.charAt(i) > '9' && username.charAt(i) < 'A') || username.charAt(i) > 'z' )
            {
                System.out.println("用户名输入格式错误，请重新输入");
                return false;
            }
            else
            {
                count ++;
            }
        }
        if (count == 0)
        {
            System.out.println("用户名中缺少字母，请重新输入");
            return false;
        }
        int index = usernameContains(userList, username);
        if (index >= 0)
        {
            System.out.println("用户名已存在，请重新输入");
            return false;
        }
        return true;
    }
    public static boolean isIdLegal(String id)
    {
        if (id.length() != 18)
        {
            System.out.println("输入错误，请重新输入");
            return false;
        }
        if (id.charAt(0) == '0')
        {
            System.out.println("输入错误，请重新输入");
            return false;
        }
        for (int i = 0; i < id.length(); i++)
        {
            boolean flag = id.charAt(i) < '0' || id.charAt(i) > '9';
            if (i < id.length() - 1)
            {
                if (flag)
                {
                    System.out.println("输入错误，请重新输入");
                    return false;
                }
            }
            else
            {
                if ((flag) && id.charAt(i) != 'X' && id.charAt(i) != 'x')
                {
                    System.out.println("输入错误，请重新输入");
                    return false;
                }
            }
        }
        return true;
    }
    public static boolean isPhoneNumberLegal(String phoneNumber)
    {
        if (phoneNumber.length() != 11)
        {
            System.out.println("输入错误，请重新输入");
            return false;
        }
        if (phoneNumber.charAt(0) == '0')
        {
            System.out.println("输入错误，请重新输入");
            return false;
        }
        for (int i = 0; i < phoneNumber.length(); i++)
        {
            if (phoneNumber.charAt(i) > '9' || phoneNumber.charAt(i) < '0')
            {
                System.out.println("输入错误，请重新输入");
                return false;
            }
        }
        return true;
    }
    public static String getVerificationCode()
    {
        Random r = new Random();
        char[] arr = new char[52];
        int[] num = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        for (int i = 0; i < arr.length; i++)
        {
            if (i < 26)
            {
                arr[i] = (char) (65 + i);
            }
            else
            {
                arr[i] = (char) (97 + i - 26);
            }
        }
        StringBuilder code = new StringBuilder();

        for (int i = 0; i < 5; i++)
        {
            if (i < 4)
            {
                int cIndex = r.nextInt(arr.length);
                code.append(arr[cIndex]);
            }
            else
            {
                int nIndex = r.nextInt(num.length);
                code.append(num[nIndex]);
            }
        }
        return code.toString();
    }
}
